// 获取股票的数据
// 日期、开盘价，收盘价，最高价，最低价，成交量
const getCodeData = (datas, prices, volumns, number) => {
    return new Promise((resolve, reject) => {
        let dates_arr = datas.split(",");
        let len = dates_arr.length;
        let prices_arr = prices.split(",");
        let prices_arr_code = chunkArray(prices_arr, 4);
        let volumns_arr = volumns.split(",")

        if(dates_arr.length < number){
            resolve([])
        } else {
            let price_arr = []
            for (let i = 1; i <= number; i++) {
                let index = len - i;
                let current_pricess = prices_arr_code[index].map(n => Number(n))
                let low_price = current_pricess[0]
                let high_price = current_pricess[0] + current_pricess[2]
                let end_price = current_pricess[0] + current_pricess[3]
                let start_price = current_pricess[0] + current_pricess[1]

                let temp_price = {
                    date: dates_arr[index],
                    start_price,
                    end_price,
                    high_price,
                    low_price,
                    volumn: volumns_arr[index]
                }
                price_arr.push(temp_price)
            }

            resolve(price_arr.reverse())
        }
    })
}

/**
 * 计算KDJ
 * KDJ指标是技术分析中常用的随机指标，主要用于判断股票的超买超卖状态和寻找买卖点。
 * 
 * 1、K、D值＞80：超买区域，可能回调
 * 2、K、D值＜20：超卖区域，可能反弹
 * 3、J值＞100：超买，J值＜0：超卖
 * 
 * @param data [{date:"日期",start_price:"开盘价",end_price:"收盘价",high_price:"最高价",low_price:"最低价"}]
 * 
 **/
function calculateKDJ(data, n = 9, kSmooth = 3, dSmooth = 3) {
    const results = [];
    let prevK = 50; // 初始K值
    let prevD = 50; // 初始D值
    
    for (let i = 0; i < data.length; i++) {
        if (i < n - 1) {
            // 前n-1天数据不足，无法计算
            results.push({
                date: data[i].date,
                end_price: data[i].end_price,
                k: null,
                d: null,
                j: null
            });
            continue;
        }
        
        // 计算最近n天的最高价和最低价
        let highestHigh = -Infinity;
        let lowestLow = Infinity;
        
        for (let j = i - n + 1; j <= i; j++) {
            if (data[j].high_price > highestHigh) highestHigh = data[j].high_price;
            if (data[j].low_price < lowestLow) lowestLow = data[j].low_price;
        }
        
        // 计算RSV
        const rsv = ((data[i].end_price - lowestLow) / (highestHigh - lowestLow)) * 100;
        
        // 计算K值
        const k = (prevK * (kSmooth - 1) + rsv) / kSmooth;
        
        // 计算D值
        const d = (prevD * (dSmooth - 1) + k) / dSmooth;
        
        // 计算J值
        const j = 3 * k - 2 * d;
        
        // 更新前一天的K值和D值
        prevK = k;
        prevD = d;
        
        results.push({
            date: data[i].date,
            end_price: data[i].end_price,
            k: parseFloat(k.toFixed(2)),
            d: parseFloat(d.toFixed(2)),
            j: parseFloat(j.toFixed(2))
        });
    }
    
    return results;
}


// 计算MACD
const calculateMACD = (prices) => {
    const ema12 = calculateEMA(prices, 12);
    const ema26 = calculateEMA(prices, 26);
    
    // 计算DIF
    const dif = [];
    for (let i = 0; i < prices.length; i++) {
        if (ema12[i] === null || ema26[i] === null) {
            dif.push(null);
        } else {
            dif.push(ema12[i] - ema26[i]);
        }
    }
    
    // 计算DEA (DIF的9日EMA)
    const dea = calculateEMA(dif.filter(val => val !== null), 9);
    // 补齐前面的空值
    while (dea.length < dif.length) {
        dea.unshift(null);
    }
    
    // 计算MACD柱
    const macd = [];
    for (let i = 0; i < prices.length; i++) {
        if (dif[i] === null || dea[i] === null) {
            macd.push(null);
        } else {
            macd.push((dif[i] - dea[i]) * 2);
        }
    }
    
    return { ema12, ema26, dif, dea, macd };
}

// 计算EMA
const calculateEMA = (prices, period) => {
    const k = 2 / (period + 1);
    const ema = [];
    
    // 第一个EMA是简单移动平均
    let sum = 0;
    for (let i = 0; i < period; i++) {
        sum += prices[i];
        ema.push(null); // 前期数据不足，设为null
    }
    ema[period-1] = sum / period;
    
    // 计算后续的EMA值
    for (let i = period; i < prices.length; i++) {
        ema.push(prices[i] * k + ema[i-1] * (1 - k));
    }
    
    return ema;
}

const addScript = (s) => {
    return new Promise((resolve, reject) => {
        const script = document.createElement("script")
        script.src = s
        document.head.append(script)
        script.onload = () => {
            resolve()
        }
        script.onerror = () => {
            reject()
        }
    })
}

const chunkArray = (arr, chunkSize = 4) => {
    const result = [];
    for (let i = 0; i < arr.length; i += chunkSize) {
        result.push(arr.slice(i, i + chunkSize));
    }
    return result;
}

const sleep = (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

export {
    addScript,
    chunkArray,
    sleep,
    getCodeData,
    calculateMACD,
    calculateKDJ,
}